/*
 * @Author: aleimu
 * @Date: 2021-03-24 13:59:53
 * @Description: 简单的防抖实现
 */

import ReactDOM from 'react-dom';
import React, { useEffect, useState, useRef } from "react";

const ChangeTable = () => {
    const [counter1, setCounter1] = useState(0);
    const [counter2, setCounter2] = useState(0);

    const inputEl = useRef(null);
    const onButtonClick = () => {
        // `current` 指向已挂载到 DOM 上的文本输入元素
        inputEl.current.focus();
    };
    const handleClick = useDebounce(function () {
        //console.count('click1')
        setCounter1(counter1 + 1)
    }, 1000)

    // 防抖函数
    function debounce(fn, delay) {
        let timer;
        return function (...arg) {
            if (timer) clearTimeout(timer)
            timer = setTimeout(() => {
                fn(arg)
                clearTimeout(timer)
            }, delay)
        }
    }

    function useDebounce(fn, delay) {
        return debounce(fn, delay) //我直接复用上面定义的防抖代码
    }
    //对之前的Debounce进行改造
    function useDebounce(fn, delay) {
        const { current } = useRef({}); //ref改变时不会改变任何值
        //且 其 .current 属性中保存一个可变值的“盒子”，其中可以保存任何值 我们就可以利用这样一个缓存机制
        // 当然他也有其他缓存机制，例如useCallBack和useMemo，但是我实在想不通，如何把timer提出去，除了使用useRef

        /*
        * 原因：因为在class组件，每次重新渲染的都是render下的jsx模板，
        * hook不一样，他每次都会重新渲染全部的hook，因此会导致闭包每次的失效，
        * 不然为什么官方文档中会去做规定，每次渲染的位置必须都是一致的
        * */
        function f(...args) {
            if (current.timer) {
                clearTimeout(current.timer);
            }
            current.timer = setTimeout(fn.bind(undefined, ...args), delay);
        }

        return f
    }

    // 引入间隔计时对count2++
    useEffect(function () {
        console.log("useEffect被调用")
        const t = setInterval(() => {
            setCounter2(x => x + 1)
        }, 1000);
        //return的函数  会在调用一个新的 effect 之前对前一个 effect 进行清理
        return clearInterval.bind(undefined, t)  //这个清除阶段 每次都会在下次useEffect执行前执行

    }, [])

    return (<div style={{ padding: 30 }}>
        <button
            ref={inputEl}
            onClick={function () {
                handleClick()
            }}
        >click</button>
        <div>{counter1}</div>
        <div>{counter2}</div>
    </div>
    )
}

export default ChangeTable